package lab2;

public class PrognozAndCorrectionMethod {
    public static void main(String[] args) {
        System.out.println("Prognoza si corectie h = 0.1 &&  n = 10");
        prognozAndCorrection(1, 1, 0.1, 10, 3);
    }

    private static void prognozAndCorrection(double x0, double u0, double h, int n, final int rungeN) {
        System.out.println("Pasul : " + rungeN);
        double xI = 0;
        double uI = 0;
        double xIMin1 = 0;
        double uIMin1 = 0;
        double xIMin2 = 0;
        double uIMin2 = 0;
        double xIMin3 = 0;
        double uIMin3 = 0;
        double newX = 0;
        double newU = 0;
        double newUPrognoza = 0;
        double newUCorectie = 0;

        for (int i = 0; i <= rungeN; i++) {
            double k1 = h * (-3 * u0 * u0 * x0 * x0);
            double k2 = h * (-3 * (x0 + h / 2) * (x0 + h / 2) * (u0 + k1 / 2) * (u0 + k1 / 2));
            double k3 = h * (-3 * (x0 + h / 2) * (x0 + h / 2) * (u0 + k2 / 2) * (u0 + k2 / 2));
            double k4 = h * (-3 * (x0 + h) * (x0 + h) * (u0 + k3) * (u0 + k3));
            newX = x0 + h;
            newU = u0 + (k1 + 2 * k2 + 2 * k3 + k4) / 6;
            xIMin3 = xIMin2;
            uIMin3 = uIMin2;
            xIMin2 = xIMin1;
            uIMin2 = uIMin1;
            xIMin1 = x0;
            uIMin1 = u0;
            xI = newX;
            uI = newU;
            System.out.println("Runge-Kutta" + i + ": " + newU);
            x0 = newX;
            u0 = newU;
        }
        for (int i = 0; i <= n - rungeN; i++) {
            newX = xI + h;

            if (rungeN == 3) {
                newUPrognoza = uI + (h / 24) *
                        (55 * (-3 * uI * uI * xI * xI) -
                                59 * (-3 * uIMin1 * uIMin1 * xIMin1 * xIMin1) +
                                37 * (-3 * uIMin2 * uIMin2 * xIMin2 * xIMin2) -
                                9 * (-3 * uIMin3 * uIMin3 * xIMin3 * xIMin3));
                newUCorectie = uI + (h / 24) *
                        (9 * (-3 * newUPrognoza * newUPrognoza * newX * newX) +
                                19 * (-3 * uI * uI * xI * xI) -
                                5 * (-3 * uIMin1 * uIMin1 * xIMin1 * xIMin1) +
                                -3 * uIMin2 * uIMin2 * xIMin2 * xIMin2);
            } else if (rungeN == 2) {
                newUPrognoza = uI + (h / 12) *
                        (23 * (-3 * uI * uI * xI * xI) -
                                16 * (-3 * uIMin1 * uIMin1 * xIMin1 * xIMin1) +
                                5 * (-3 * uIMin2 * uIMin2 * xIMin2 * xIMin2));
                newUCorectie = uI + (h / 12) *
                        (5 * (-3 * newUPrognoza * newUPrognoza * newX * newX) +
                                8 * (-3 * uI * uI * xI * xI) -
                                -3 * uIMin1 * uIMin1 - xIMin1 * xIMin1);
            } else if (rungeN == 1) {
                newUPrognoza = uI + (h / 2) *
                        (3 * (-3 * uI * uI * xI * xI) -
                                -3 * uIMin1 * uIMin1 * xIMin1 * xIMin1);
                newUCorectie = uI + (h / 2) *
                        (-3 * newUPrognoza * newUPrognoza * newX * newX +
                                -3 * uI * uI * xI * xI);
            }
            System.out.println("Prognoza si corectie U: " + i + ": " + newUCorectie);
            xIMin3 = xIMin2;
            uIMin3 = uIMin2;
            xIMin2 = xIMin1;
            uIMin2 = uIMin1;
            xIMin1 = xI;
            uIMin1 = uI;
            xI = newX;
            uI = newUCorectie;
        }
    }
}
